package com.gutsyzhan.bilibili.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.gutsyzhan.bilibili.constant.UserConstant;
import com.gutsyzhan.bilibili.exception.ConditionException;

import java.util.Calendar;
import java.util.Date;

public class TokenUtil {
    public static final String ISSUER = "默认签发者";

    /**
     * 生成Token
     */
    public static String generateToken(Long userId, Integer field, Integer amount) throws Exception {
        //使用RSA的公钥和私钥来生成加密算法
        Algorithm algorithm = Algorithm.RSA256(RSAUtil.getPublicKey(), RSAUtil.getPrivateKey());
        //设置过期时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        //用户token有效期变更为3小时
        calendar.add(field, amount);
        //设置唯一身份标识为userId
        return JWT.create().withKeyId(String.valueOf(userId)).withIssuer(ISSUER).withExpiresAt(calendar.getTime())
                .sign(algorithm);
    }

    /**
     * 校验Token
     */
    public static Long verifyToken(String token){
        //使用RSA的公钥和私钥来生成加密算法
        try{
            Algorithm algorithm = Algorithm.RSA256(RSAUtil.getPublicKey(), RSAUtil.getPrivateKey());
            //生成验证类
            JWTVerifier jwtVerifier = JWT.require(algorithm).build();
            DecodedJWT decodedJWT = jwtVerifier.verify(token);
            String userId = decodedJWT.getKeyId();
            return Long.valueOf(userId);
        }catch (TokenExpiredException e){
            throw new ConditionException("555", "token过期!");
        }catch (Exception e){
            throw new ConditionException("非法的用户token!");
        }
    }

    public static String generateAccessToken(Long userId)throws Exception {
        return generateToken(userId, Calendar.HOUR, UserConstant.ACCESS_TOKEN_DEFAULT_HOURS);
    }

    public static String generateRefreshToken(Long userId)throws Exception {
        return generateToken(userId, Calendar.DAY_OF_MONTH, UserConstant.REFRESH_TOKEN_DEFAULT_DAYS);
    }
}
